<?php
/** @noinspection PhpUnused */
declare(strict_types=1);

namespace app\shop\controller;

use app\common\facade\Token;
use app\shop\enums\sms\SmsTemplateCode;
use app\shop\exception\FailException;
use app\shop\exception\ParamsErrorException;
use app\shop\library\ShopAuth;
use app\shop\logic\UserLogic;
use app\shop\model\user\UserModel;
use app\shop\validate\UserValidate;
use ba\Captcha;
use ba\Random;
use think\db\exception\DbException;
use think\facade\Db;
use think\facade\Request;
use think\response\Json;
use Throwable;

/**
 * @property UserLogic $logic
 */
class UserController extends BaseController
{
    protected string $validateClassName = UserValidate::class;

    protected array $noNeedLogin = ['resetPassword'];

    public function __construct(UserLogic $userLogic)
    {
        parent::__construct();

        $this->logic = $userLogic;
    }

    /**
     * 面板数据
     * @return Json
     * @throws DbException
     */
    public function dashboard(): Json
    {
        $params = $this->getInput(true);
        $user = ShopAuth::instance()->getUser();
        $params['user_id'] = $user->id;
        $result = $this->logic->dashboard($params);

        return $this->success($result);
    }

    public function info(): Json
    {
        return $this->success($this->auth->getUserInfo());
    }

    /**
     * 编辑
     * @return Json
     * @throws FailException
     * @throws ParamsErrorException
     */
    public function edit(): Json
    {
        $params = $this->postInput(true);

        $this->validateData($params, 'edit');

        $result = $this->logic->edit($params);

        return $this->success($result);
    }

    /**
     * 余额日志
     * @return Json
     */
    public function balanceLog(): Json
    {
        $params = $this->getInput(true);

        $result = $this->logic->balanceLog($params);

        return $this->success($result);
    }

    /**
     * 修改密码
     * @return Json
     * @throws ParamsErrorException
     */
    public function changePassword(): Json
    {
        $params = $this->postInput(true);

        $this->validateData($params, 'change_password');

        $user = UserModel::where('id', $params['user_id'])->findOrEmpty();

        if ($user->isEmpty()) {
            throw new ParamsErrorException('用户未注册');
        }

        if ($user->password !== encrypt_password($params['old_password'], $user->salt)) {
            throw new ParamsErrorException('旧密码不正确');
        }

        $result = $this->updatePassword($user, $params['new_password']);

        return $this->success($result);
    }

    private function updatePassword(UserModel $user, string $password): bool
    {
        $salt     = Random::build('alnum', 16);
        $password = encrypt_password($password, $salt);

        $user->password = $password;
        $user->salt     = $salt;

        return $user->save();
    }

    /**
     * 重置密码
     * @return Json
     * @throws ParamsErrorException
     * @throws Throwable
     */
    public function resetPassword(): Json
    {
        $params = $this->postInput();

        $this->validateData($params, 'reset_password');

        $user = UserModel::where('mobile', $params['phone'])->findOrEmpty();

        if ($user->isEmpty()) {
            throw new ParamsErrorException('用户未注册');
        }

        $captchaId = $user->mobile . SmsTemplateCode::USER_RETRIEVE_PWD;
        if (false === (new Captcha())->check($params['sms_captcha_code'], $captchaId)) {
            throw new ParamsErrorException('验证码错误');
        }

        $result = $this->updatePassword($user, $params['new_password']);

        return $this->success($result);
    }

    /**
     * 账户验证
     * @return Json
     * @throws ParamsErrorException
     * @throws Throwable
     */
    public function verification(): Json
    {
        $params = $this->postInput(true);

        $this->validateData($params, 'verification');

        $user = ShopAuth::instance()->getUser();

        if (false === (new Captcha())->check($params['sms_captcha_code'], $user->mobile . SmsTemplateCode::USER_MOBILE_VERIFY)) {
            throw new ParamsErrorException('验证码错误');
        }

        if (!isset($params['password']) || $user->password !== encrypt_password($params['password'], $user['salt'])) {
            throw new ParamsErrorException('密码错误');
        }

        $uuid = Random::uuid();
        Token::set($uuid, 'phone-pass', $user->id, 600);

        return $this->success([
            'verificationToken' => $uuid,
        ]);
    }

    /**
     * 修改绑定手机号
     * @return Json
     * @throws ParamsErrorException
     * @throws Throwable
     */
    public function changeBind(): Json
    {
        $params = $this->postInput(true);

        $this->validateData($params, 'change_bind_phone');

        $user = ShopAuth::instance()->getUser();

        if (!Token::check($params['verification_token'], 'phone-pass', $user->id)) {
            throw new ParamsErrorException('账户信息验证失败，请刷新重试');
        }

        $captcha = new Captcha();
        if (!$captcha->check($params['sms_captcha_code'], $params['phone'] . SmsTemplateCode::USER_CHANGE_MOBILE)) {
            throw new ParamsErrorException('验证码错误');
        }

        $phoneCount = UserModel::where('mobile', $params['phone'])->count();
        if ($phoneCount > 0) {
            throw new ParamsErrorException('手机号已被绑定');
        }

        $user->mobile = $params['phone'];
        $user->save();

        Token::delete($params['verification_token']);

        return $this->success();
    }

    public function qrCode()
    {
        $user = ShopAuth::instance()->getUser();
        $uid = $user->id;
        $rootPath = rtrim($_SERVER['DOCUMENT_ROOT'], "public");
        require_once $rootPath . "/extend/phpqrcode/phpqrcode.php";
        // 加载海报背景图
        $logoPath = $_SERVER['DOCUMENT_ROOT'] . Db::name('shop_setting')->field('name,value')->where('name','logo')->value('value');
        $qrCodeImagePath = self::getqrCode($uid,$logoPath);
        if(! Db::name('shop_setting')->field('name,value')->where('name','share_image')->value('value')){
            return $this->success([
                'qrCodeUR' => $qrCodeImagePath,
            ]);
        }
        $backgroundImagePath = $_SERVER['DOCUMENT_ROOT'] . Db::name('shop_setting')->field('name,value')->where('name','share_image')->value('value');


        $backgroundImage=   imagecreatefromstring(file_get_contents($backgroundImagePath));
        if (!$backgroundImage) {
            die('无法加载背景图');
        }

        // 载入二维码
        $qrCodeImage = imagecreatefrompng($qrCodeImagePath);
        if (!$qrCodeImage) {
            die('无法加载二维码');
        }
        // 获取背景图和二维码的宽高
        $backgroundWidth = imagesx($backgroundImage);
        $backgroundHeight = imagesy($backgroundImage);
        $qrCodeWidth = imagesx($qrCodeImage);
        $qrCodeHeight = imagesy($qrCodeImage);

        // 计算二维码在背景图上的位置（底部中间）
        $qrCodeX = ($backgroundWidth - $qrCodeWidth - 1) / 2;
        $qrCodeY = $backgroundHeight - $qrCodeHeight - 145; // 20是底部与二维码的间距
        // 合并二维码到背景图
        imagecopy($backgroundImage, $qrCodeImage, $qrCodeX, $qrCodeY, 0, 0, $qrCodeWidth, $qrCodeHeight);
        // 保存合成后的图片
        $time = time();
        $mergedImagePath = $_SERVER['DOCUMENT_ROOT'] . "/static/merged_qrcode/" . $time . "_merged.png";
        imagepng($backgroundImage, $mergedImagePath);

        // 释放内存
        imagedestroy($backgroundImage);
        imagedestroy($qrCodeImage);
        $code = Db::name('shop_user')->where('id',$uid)->value('code');
        if(!isset($code) || $code==''){
            $mobile = Db::name('shop_user')->where('id',$uid)->value('mobile');
            if(isset($mobile)){
                $code = substr($mobile, -6);
            }else{
                $code = (string)mt_rand(1000, 9999);
                $code .= $uid;
            }

            if(Db::name('shop_user')->where('code',$code)->value('id')){
                $code .= 1;
            }
            Db::name('shop_user')->where('id',$uid)->update(['code'=>$code]);
        }
        $text = "邀请码：".$code;
        $image = imagecreatefrompng($mergedImagePath);
        // 设置文字的字体文件路径，确保该路径有效
        $fontPath =  $_SERVER['DOCUMENT_ROOT'] . "/static/merged_qrcode/font.ttf";
        // 分配颜色和透明度
        $black = imagecolorallocate($image, 0, 0, 0);
        $transparent = imagecolorallocatealpha($image, 0, 0, 0, 127);

        // 设置文字位置和角度
        $x = ($backgroundWidth - $qrCodeWidth - 1) / 2 -30;
        $y = 1280;
        $angle = 0;
        // 在图片上添加文字
        imagettftext($image, 20, $angle, $x, $y, $black, $fontPath, $text);
        $mergedImagePath2 = $_SERVER['DOCUMENT_ROOT'] . "/static/merged_qrcode/" . $time.'1' . "_merged.png";
        imagepng($image, $mergedImagePath2);
        // 释放内存
        imagedestroy($image);
        // 返回二维码图片的URL地址
        $request = Request::instance();
        $domain = $request->domain();

        $qrCodeURL = $domain . "/static/merged_qrcode/" . $time.'1' . "_merged.png";
        return $this->success([
            'qrCodeUR' => $qrCodeURL,
        ]);


    }

    //小程序分享二维码
    public function getqrCode($user_id,$logoPath = ''){
        $code = $user_id;
        $request = Request::instance();
        $domain = $request->domain();
        $url = $domain."/h5/#/pagesMember/pages/login/login?pid=" . $code;
        $img = time() . rand(0, 999);
        //生成二维码图片
        $errorCorrectionLevel = 'L';    //容错级别
        $matrixPointSize = 4;            //生成图片大小
        $img = md5($img) . '.png';
        $file_path = root_path()  . 'public/user/share/';

        $path = $file_path;
        if (!file_exists($path)) {
            //检查是否有该文件夹，如果没有就创建，并给予最高权限
            mkdir($path, 0777, true);
        }
        $filename = $path . $img;
        include_once root_path() . 'extend/phpqrcode/phpqrcode.php';
        \QRcode::png($url, $filename, $errorCorrectionLevel, $matrixPointSize, 2);
        // $image = imagecreatefrompng($filename);
        // // 设置透明背景
        // $width = imagesx($image);
        // $height = imagesy($image);

        // // 创建一个真彩色图像
        // $background = imagecreatetruecolor($width, $height);
        // // 设置为透明
        // imagealphablending($background, false);
        // imagesavealpha($background, true);

        // // 设置透明背景
        // $transparent = imagecolorallocatealpha($background, 0, 0, 0, 127);
        // imagefill($background, 0, 0, $transparent);
        // // 将二维码复制到透明背景
        // imagecopy($background, $image, 0, 0, 0, 0, $width, $height);
        // $filename = $path .'1'. $img;
        // imagepng($background, $filename);
        // // // 释放内存
        // // imagedestroy($image);
        // imagedestroy($background);
        $QR = $filename;                //已经生成的原始二维码图片文件
        $QR = imagecreatefromstring(file_get_contents($QR));

        if ($logoPath !== FALSE) {
            $logo = imagecreatefromstring(file_get_contents($logoPath));
            $QR_width = imagesx($QR);//二维码图片宽度
            $QR_height = imagesy($QR);//二维码图片高度
            $logo_width = imagesx($logo);//logo图片宽度
            $logo_height = imagesy($logo);//logo图片高度
            $logo_qr_width = $QR_width / 5;
            $scale = $logo_width/$logo_qr_width;
            $logo_qr_height = $logo_height/$scale;
            $from_width = ($QR_width - $logo_qr_width) / 2;
            //重新组合图片并调整大小
            imagecopyresampled($QR, $logo, (int)round($from_width), (int)round($from_width), 0, 0, (int)round($logo_qr_width),
                (int)round($logo_qr_height), (int)round($logo_width), (int)round($logo_height));
        }

        imagepng($QR, $filename);
        imagedestroy($QR);
        //保存图片,销毁图形，释放内存

        $rand = "/user/share/" . $img;
        $qr_code =$rand;

        $qrCodeURL = $domain . $qr_code;
        return $qrCodeURL;
    }


    public function teamList(): Json
    {
        $params = $this->postInput(true);

        $result = $this->logic->teamList($params);

        return $this->success($result);

    }

    /**
     * 关注列表
     * @return Json
     */
    public function interestUserList(): Json
    {
        $params = $this->postInput(true);
        $result = $this->logic->interestUserList($params);
        return $this->success($result);
    }

    /**
     * 去关注
     * @return Json
     */
    public function toInterest(): Json
    {
        $params = $this->postInput(true);
        $result = $this->logic->toInterest($params);
        return $this->success($result);
    }

    public function addLive()
    {
        $params = $this->postInput(true);
        $info = Db::name('shop_user_live')->where('user_id',$params['user_id'])->find();
        if(!$info){
            $res = Db::name('shop_user_live')->where('user_id',$params['user_id'])->insert([
                'user_id' => $params['user_id'],
                'name' => $params['name'],
                'phone' => $params['phone'],
                'create_time' => time()
            ]);
            if($res){
                return $this->success('成功');
            }else{
                throw new FailException('失败');
            }
        }else{
            throw new FailException('已申请');
        }

    }

    public function levelList()
    {
        $list = Db::name('recommend_level')->select();
        return $this->success($list);
    }

}
